#pragma once

#include <iostream>
#include <string>
#include <memory>
#include <functional>

#include "Socket.hpp"
#include "ThreadPool.hpp"

using namespace My_Socket;
using namespace My_ThreadPool;

using hander_t = std::function<bool(SockPtr, InetAddr)>;
using threadpool_t = std::function<void()>;

class TcpServer
{
public:
    TcpServer(int port) : _port(port), _socket(std::make_unique<TcpSocket>())
    {
    }
    void InitServer(hander_t hander)
    {
        _hander = hander;
        _socket->BuildTcpSocket(_port);
    }
    void Loop()
    {
        _isrunning = true;
        std::string recvstr;
        while (true)
        {
            InetAddr cliaddr;
            SockPtr sp = _socket->Accepter(&cliaddr);
            if (sp)
            {
                LOG(LogLevel::DEBUG) << "get a new client, info is: " << cliaddr.GetStrIpPort();
                ThreadPool<threadpool_t>::getinstance()->Equeue([this, cliaddr, sp]()
                                                                { this->_hander(sp, cliaddr); });
            }
        }
    }
    hander_t GetHander() {return _hander;}
    ~TcpServer()
    {
    }

private:
    std::unique_ptr<Socket> _socket;
    int _port;
    bool _isrunning;
    hander_t _hander;
};